import { computed, nextTick, ref, watch } from 'vue';
import AllKey from '../data/key';
import doubleSpell from '/public/chowder.json'
import dict from '/public/baseDict.json'
export default function(props, { emit }) {
  //声明变量
const show = ref(props.showKeyboard);
const showDiction = ref(false);
const equipmentType = ref('pc');
const def_mode = ref('cn');
const old_mode = ref('');
const mainMode = ref('');
const cn_input = ref('');
const cn_list_str = ref([]);
const l_min = ref(0);
const l_max = ref(props.maxQuantify);
const cursorPosition = ref(-1);
//数字键盘
const number_keys = computed(() => {
  let list = AllKey.number || [];
  return list.filter((num) => !isNaN(Number(num)));
});

//触发事件
const keyEvent = computed(() => {
  let result = 'mousedown';
  if (
    equipmentType.value === 'phone' ||
    'ontouchstart' in document.documentElement
  ) {
    result = 'touchstart';
  }
  return result;
});

//样式
const previousStyleFn = computed(() => {
  let result = { background: '#a7a7a7' };
  if (l_min.value > 0) {
    result.background = '#344a5d';
  }
  return result;
});
const nextPageStyleFn = computed(() => {
  let result = { background: '#a7a7a7' };
  if (cn_list_str.value.length > l_max.value) {
    result.background = '#344a5d';
  }
  return result;
});

//数字键盘
const number_keys2 = computed(() => {
  let numKeyList = AllKey.number;
  let biaodianKeyList = AllKey.biaodian;

  let resultArray = numKeyList;
  if (['num', 'id_card', 'di_git'].includes(mode.value)) {
    if (!old_mode.value) {
      resultArray = numKeyList.map((key) => {
        if (['X', '.'].includes(key) && mode.value === 'num') {
          return '';
        }
        if (['.'].includes(key) && mode.value === 'id_card') {
          return '';
        }
        if (['X', '.'].includes(key) && mode.value === 'di_git') {
          if (key === '.') {
            return '';
          }
          return '.';
        }
        return key;
      });
    }
  } else {
    resultArray = biaodianKeyList;
  }
  return resultArray;
});

//英文按键
const letter_keys = computed(() => {
  return mode.value === 'en_cap' ? AllKey.cap_letter : AllKey.letter;
});

const cut_cn_list = computed(() => {
  if (cn_list_str.value) {//如果存在中文列表
    let result = cn_list_str.value.slice(l_min.value, l_max.value);//截取中文列表
    if (equipmentType.value === 'phone') {
      result = cn_list_str.value;
    }
    return result;//返回截取后的中文列表
  }
  return [];
});

//修改模式
const mode = computed({
  get() {
    return def_mode.value;
  },
  set(val) {
    if (JSON.stringify(dict) === '{}') {
      if (['cn', 'password'].includes(val)) {
        val = 'password';
      }
      mainMode.value = 'noCn';
    }
    if (['password'].includes(val)) {
      mainMode.value = 'noCn';
    }
    old_mode.value = def_mode.value;
    def_mode.value = val;
    if (val !== 'cn') {
      cn_list_str.value = [];
      cn_input.value = '';
    }
    methods.initKeyColor();
    showDiction.value = false;
    emit('changeMode', val);
  },
});
  //判断当前设备大小
  if (window.screen.width < props.screen) {
    //当前设备为移动设备
    equipmentType.value = 'phone';
  }
  let input: HTMLInputElement = null;
  const methods = {
    //初始化键盘颜色
    initKeyColor() {
      nextTick(() => {
        let keyDivList = document.querySelectorAll(
          '.my-keyboard .key:not([bindtouchendAndmouseup])'
        );

        let fn = function (e) {
          if (!Array.from(e.currentTarget.classList).includes('key_hide')) {
            e.currentTarget.style.background = '#fff';
          }
        };
        for (let item of keyDivList) {
          item.setAttribute('bindtouchendAndmouseup', 'true');
          item.addEventListener('touchend', fn);
          item.addEventListener('touchmove', fn);
          item.addEventListener('mouseup', fn);
          item.addEventListener('mousemove', fn);
        }
      });
    },
    //是否显示键盘
    isShowDiction(e) {
      e.preventDefault();
      showDiction.value = true;
    },
    //输入绑定键盘
    inputBindKeyboard() {
      nextTick(() => {
        //每个input添加事件
        const inputAll = document.querySelectorAll(
          "[keyboard='true']:not([bindkeyboard])"
        );
        inputAll.forEach((e) => {
          e.setAttribute('bindkeyboard', 'true');
          e.addEventListener('focus', methods.showKeyBoardFn);
          e.addEventListener('click', () => {
            setTimeout(() => {}, 100);
          });
          if (props.blurHide) {
            e.addEventListener('blur', () => {
              show.value = false;
            });
          }
          // }
        });
      });
    },
    showKeyBoardFn(e) {
      e.preventDefault();
      mainMode.value = '';
      if (props.showKeyboard) return;
      input = e.target;
      show.value = true;
      mode.value = e.target.dataset.mode || 'cn';
      old_mode.value = '';
    },
    //设置输入值
    setInputValue(key: string | number, type: string = 'set') {
      let cursor = input.selectionStart; //光标初始位置
      let tagName = input.tagName;

      let isContenteditable = !!input.getAttribute('contenteditable');
      let value = input.value;
      if (isContenteditable) {
        cursor = methods.getCaretPosition(input);
        value = input.innerText;
      }
      if (type === 'del') {
        if (cursor > 0) {
          let cursorEnd = input.selectionEnd;
          if (cursorEnd != cursor && tagName === 'INPUT ') {
            value = value
              ?.split('')
              ?.filter((item, index) => {
                if (index < cursor || index >= cursorEnd) {
                  return item;
                }
              })
              ?.join('');
          } else {
            value = methods.delStringLast(value, cursor);
            cursor -= 1;
          }
        }
      } else {
        value = methods.insertString(value, key, cursor);
        if (key.charCodeAt(key) > 127 || key.charCodeAt(key) > 94) {
          cursor += key.length;
        } else {
          cursor += 1;
        }
      }

      if (isContenteditable) {
        input.innerText = value;
        let range = document.createRange();
        let sel = window.getSelection();
        range.setStart(input.childNodes[0], cursor);
        range.collapse(true);
        sel?.removeAllRanges();
        sel?.addRange(range);
        emit('contenteditableInput', input.innerText);
      } else {
        input.value = value;
        input.selectionStart = cursor;
        input.selectionEnd = cursor;
        input.dispatchEvent(new Event('input', { bubbles: true }));
      }
    },
    //获取光标位置
    getCaretPosition(element) {
      let carePos = 0, 
        sel,
        range;

      if (window.getSelection) {
        sel = window.getSelection();
        if (sel?.rangeCount) {
          range = sel.getRangeAt(0);

          if (range.commonAncestorContainer.parentNode == element) {
            carePos = range.endOffset;
            if (
              range.commonAncestorContainer
              // range.commonAncestorContainer.length !=
              // range.commonAncestorContainer.data.trim().length
            ) {
              carePos -= 1;
            }
          }
        }
      }

      cursorPosition.value = carePos;
      return carePos;
    },
    /**删除字符串的某个字符*/
    delStringLast(text, index) {
      if (index < 0) return;
      let arrText = text.split('');
      if (index > 0) {
        arrText[index - 1] = '';
      } else {
        arrText[index] = '';
      }

      arrText = arrText.filter((item) => item);
      const endIndex = arrText.length - 1;
      if (arrText[endIndex] === '') {
        arrText[endIndex] = '';
      }
      let result = arrText.join('');

      return result;
    },
    /**字符串插入文字 */
    insertString(text, input, index) {
      let arrText = text.split('');
      arrText.splice(index, 0, input);
      return arrText.join('');
    },
    //隐藏
    HideKey() {
      show.value = false;
      input.blur();
    },
    //鼠标按下时
    mousedown(e) {
      e.stopImmediatePropagation();
    },
    //点击键盘时
    clickKey(e, key, pass) {
      e.preventDefault(); //阻止默认事件
      e.stopImmediatePropagation(); //阻止冒泡
      e.target.style.background = '#d0d0d0'; //点击时改变背景色
      if (input !== document.activeElement) return; 
      if (mode.value === 'cn' && !pass) { //如果是中文模式
        cn_input.value += key;  //拼音输入框添加拼音
        const specialPinYin = ['u', 'v', 'i'].includes(cn_input.value.split('')[0]); //判断是否是特殊拼音
        if (specialPinYin) {  //如果是特殊拼音
          if (!cn_list_str.value.length) {  //如果没有拼音列表
            //@ts-ignore
            cn_list_str.value = [key]; //拼音列表添加拼音
          } else {
            const value = cn_list_str.value[0] + key; //拼音列表第一个拼音加上当前拼音
            //@ts-ignore
            cn_list_str.value[0] = value; //拼音列表第一个拼音替换为新的拼音
          }
          return;
        }
        methods.findChinese('add', key); //查找中文
      } else {
        methods.setInputValue(key); //设置输入值
      }
      emit('clickKey', key);
    },
    findChinese(type?: string, key?: number) {
      // type = del key不需要传，type = add key必须要传
      l_min.value = 0; //最小值
      l_max.value = props.maxQuantify;  //最大值
      const pinYinList = cn_input.value.split(''); //拼音列表
      let pinYin = pinYinList[pinYinList.length - 1]; //当前拼音

      let re = new RegExp(`^${pinYin}\\w*`); //正则,匹配当前拼音开头的拼音
      let keys = Object.keys(dict)  //获取拼音字典的key
        .filter((item) => {  //过滤
          let strList = pinYin.split(''); //当前拼音转数组

          const temp = ['h', 'o', 'n', 'a', 'e'].includes(
            strList[strList.length - 1]  //判断是否是特殊拼音
          );
          if (pinYin.length >= 2 && !temp) { //如果是特殊拼音
            if (item === pinYin) return true; //如果拼音字典的key等于当前拼音，返回true
          } else {
            let result = re.test(item);   //如果不是特殊拼音，返回正则匹配结果
            return result;
          }
        })
        .sort();
      cn_list_str.value =
        keys.length > 1 ? keys.reduce((a, b) => a + dict[b], '') : dict[keys[0]]; //如果拼音列表大于1，拼接拼音列表，否则直接赋值
    console.log('cn_list_str.value-->>',cn_list_str.value);
      if (!cn_list_str.value || (!cn_list_str.value.length && type === 'del')) { //如果拼音列表不存在或者拼音列表长度为0并且type为del
        cn_input.value = cn_input.value.replace(
          new RegExp(`(.*)${key}`),
          `$1'${key}`
        );
      }

      if (!cn_list_str.value && !Array.isArray(cn_list_str.value)) {
        cn_list_str.value = [];
      }

      keys = cn_input.value.split('');

      if (keys.length >= 2) {
        cn_list_str.value = [];
        methods.findDoubleSpell(); 
      }
    },
    findDoubleSpell() {
      let keys = cn_input.value.split('');
      const partDict = doubleSpell[cn_input.value.charAt(0)];
      if (!partDict) return;
      if (['an'].includes(keys[keys.length - 1])) {
        let tempStr = keys[keys.length - 2];
        if (['n'].includes(tempStr.charAt(tempStr.length - 1))) {
          let newTempStr = tempStr.slice(0, tempStr.length - 1);
          keys = [
            newTempStr,
            tempStr.slice(tempStr.length - 1) + keys[keys.length - 1],
          ];
          cn_input.value = keys.join('');
        }
      }

      let keyResult = Object.keys(partDict).filter((key) => {
        const keys = key.split('');
        const cn_inputList = cn_input.value.split('');
        const isLen = cn_inputList.length === keys.length;
        if (!isLen) return;
        let result = true;
        for (let i = 0; i < keys.length; i++) {
          if (keys[i].charAt(0) != cn_inputList[i].charAt(0)) {
            result = false;
          } else {
            const keyItemList = keys[i].split('');
            const strList = cn_inputList[i].split('');
            for (let j = 0; j < strList.length; j++) {
              if (!strList[j]) break;
              if (keyItemList[j] != strList[j]) {
                result = false;
              }
            }
          }
        }
        if (result && isLen) {
          return partDict[key];
        }
      });

      let strList = [];
      let singleDictList = [];
      const singleDict = dict;
      for (let key of keyResult) {
        let keyList = key.split('');
        strList.push(partDict[key].split(','));
        for (let item of keyList) {
          if (singleDict[item]) {
            singleDictList.push(singleDict[item].split(''));
          }
        }
      }
      if (!keyResult.length && keys.length) {
        for (let item of keys) {
          if (singleDict[item]) {
            singleDictList.push(singleDict[item].split(''));
          }
        }
      }

      singleDictList = Array.from(new Set(singleDictList.flat(2)));
      strList = strList
        .flat(2)
        //@ts-ignore
        .sort((a, b) => {
          if (b.length > a.length) return -1;
        })
        .reverse();
      //@ts-ignore
      cn_list_str.value = strList.concat(singleDictList);
    },
    //点击数字
    clickNumber(e, key) {
      if (!AllKey.number.find((k) => k === key) && def_mode.value != 'biaodian') {
        return;
      }

      if (input !== document.activeElement) return;
      e.preventDefault();
      e.target.style.background = '#d0d0d0';
      if (mode.value === 'cn' && cn_input.value !== '') {
        let value = cut_cn_list.value[parseInt(key) - 1];
        if (!value) return;
        methods.selectCN(value);
        methods.setInputValue(value);
      } else {
        methods.setInputValue(key);
      }
      emit('clickNumber', key);
    },
    //选择中文
    selectCN(text) {
      console.log('selectCN');
      let strList = cn_input.value.split('');
      if (strList.length === 1 || text.length >= strList.length) {
        cn_input.value = '';
        cn_list_str.value = [];
        l_min.value = 0;
        l_max.value = props.maxQuantify;
        return;
      }
      methods.setCn_input(text);
    },
    //设置中文输入
    setCn_input(text) {
      const singleDict = dict;
      let itemList = [];
      for (let key in singleDict) {
        let value = singleDict[key];
        if (typeof value === 'string') {
          let valueList = value.split('');
          let item = valueList.find((item) => item === text);
          if (item) {
            itemList.push(key);
          }
        }
      }
      let str = '';
      const cn_inputList = cn_input.value.split('');
      for (let i = 0; i < cn_inputList.length; i++) {
        let item = cn_inputList[i];
        for (let key of itemList) {
          let list = key.split('');
          let count = 0;
          for (let k = 0; k < list.length; k++) {
            if (key.charAt(k) === item.charAt(k)) {
              count += 1;
              if (
                k === 0 &&
                item.length != key.length &&
                key.length > item.length
              ) {
                // 用于处理首单词缩写法
                str = item;
              }
            }
            if (count === list.length) {
              str = item;
            }
          }
        }
      }
      cn_input.value = cn_inputList.filter((item) => item != str).join('');
      methods.findChinese();
    },
    //点击中文
    clickCN(e, text) {
      e.preventDefault();
      e.stopImmediatePropagation();
      showDiction.value = false;
      methods.setInputValue(text);
      methods.selectCN(text);

      emit('clickCN', text);
    },
    //cap值改变
    cap_change() {
      if (mainMode.value === 'noCn') {
        mode.value = mode.value === 'en_cap' ? 'password' : 'en_cap';
        return;
      }
      mode.value = mode.value === 'en_cap' ? 'en' : 'en_cap';
    },
    //cn值改变
    cn_change(params) {
      if (mainMode.value === 'noCn') {
        mode.value = params === 'en' ? 'cn' : 'en';
      } else {
        mode.value = params;
      }
      cn_input.value = '';
      cn_list_str.value = [];
    },
    //返回按键
    Fanhui() {
      if (showDiction.value) {
        showDiction.value = false;
        return;
      }

      if (['num', 'biaodian'].includes(old_mode.value) || !old_mode.value) {
        mode.value = 'cn';
        return;
      }

      mode.value = old_mode.value;
    },
    //上一步
    previous_page(e) {
      e.preventDefault();
      e.stopImmediatePropagation();
      if (l_min.value > 0) {
        l_min.value = l_min.value - props.maxQuantify;
        l_max.value = l_max.value - props.maxQuantify;
      }
    },
    //下一步
    next_page(e) {
      e.preventDefault();
      e.stopImmediatePropagation();
      if (cn_list_str.value.length > l_max.value) {
        l_min.value += props.maxQuantify;
        l_max.value += props.maxQuantify;
      }
    },
    //删除
    del(e) {
      console.log('del');
      e.stopImmediatePropagation();
      e.preventDefault();
      if (input !== document.activeElement) return;
      if (mode.value === 'cn' && cn_input.value !== '' && !showDiction.value) {
        cn_input.value = methods.delStringLast(cn_input.value, cn_input.value.length);

        if (cn_input.value === '') {
          cn_list_str.value = [];
          return;
        }
        const specialPinYin = ['u', 'v', 'i'].includes(cn_input.value.split('')[0]);
        if (cn_list_str.value && cn_list_str.value.length === 1 && specialPinYin) {
          //@ts-ignore
          cn_list_str.value = [cn_input.value];
          return;
        }
        let re = new RegExp(`^${cn_input.value}\\w*`);
        let keys = Object.keys(dict)
          .filter((key) => {
            const result = re.test(key);
            return result;
          })
          .sort();

        cn_list_str.value =
          (keys.length > 1
            ? keys.reduce((a, b) => a + dict[b], '')
            : dict[keys[0]]) || ''.split('');

        methods.findChinese('del');
        emit('del', JSON.parse(JSON.stringify(cn_input.value)));
      } else {
        methods.setInputValue(null, 'del');
      }
    }
  }
  return {
    methods
  }
}
